#ifndef _FUN_H_
#define _FUN_H_

#include "data.h"


/************************
 *
 *
 *    EEPROM Functions
 *
 *
 *************************/


/************************
 *  Read text from eeprom
 *************************/
void read_text(uint16_t n, char *text) {
  n *= 16;
  for(byte i = 0; i < 16; i++) {
    text[i] = EEPROM.read(n + i);
  }

#if DEBUG
  Serial.print("EEPROM read: ");
  Serial.println(text);
#endif
}

/************************
 *
 *
 *    FILE Functions
 *
 *
 *************************/


/************************
 *  Parse integer from file
 *************************/
uint16_t read_int(Fat16 *file) {
  char c;
  uint16_t n = 0;
  // search number
  while(c = file->read(), c < '0' || c > '9');
  // parse number
  do {
    n *= 10;
    n += c - '0';
  } 
  while(c = file->read(), c >= '0' && c <= '9');
  return n;
}

/******************************
 *  Parse byte address from file
 *******************************/
void read_addr(Fat16 *file, byte *addr, byte dim) {
  for(byte i = 0; i < dim; i++) {
    *(addr + i) = read_int(file);
  }
}


/************************
 *  Read line from file
 *************************/
boolean read_line(Fat16 *file, char *buffer) {
#if DEBUG
  Serial.print("FILE read line: ");
#endif
  char *p = buffer;
  char c;
  // skip non-printable characters and spaces at begin of the line
  while((c = file->read()), c < 32 && c > 0);
  // if EOF, return
  if(c < 0) {
    *p = '\0';
#if DEBUG
    Serial.println("EOF");
#endif
    return false;
  }

  // read chars until EOL
  do {
    *p = c;
    p++;  
  } 
  while ((c = file->read()), c != 10 && c != 13 && c >= 0);
  *p = '\0';
#if DEBUG
  Serial.println(buffer);
#endif
  return true;
}


/************************
 *
 *
 *    HTTP Functions
 *
 *
 *************************/
 /*******************************
 *  Send data direct from eeprom
 *******************************/
void eeprom2http(uint16_t code, EthernetClient *conn) {
  char c;
  code *= 16;
  while(c = EEPROM.read(code), c > 31) {
    conn->print(c);
#if DEBUG
    Serial.print(c);
#endif

    code++;
  }
#if DEBUG
  Serial.println();
#endif
}


/**********************
 * Get next tag from http
 ***********************/
char get_tag(EthernetClient *client) {
  uint16_t c;
  // search tag begin
  while(c = client->read(), c != TAG_BEGIN && c != -1) {
#if DEBUG
    Serial.print((char)c);
#endif
  }
  // when data aren't available, return zero
  if(c == -1)
    return 0;

  // else get tag character  
  c = client->read();
#if DEBUG
  Serial.print((char)c);
#endif
  return c;
}

/************************
 *  Read line from http
 *************************/
boolean http_line(EthernetClient *client, char *buffer) {
#if DEBUG
  Serial.print("HTTP read line: ");
#endif
  char *p = buffer;
  char c;
  // skip non-printable characters and spaces at begin of the line
  while((c = client->read()), c < 32 && c > 0);
  // if EOF, return
  if(c < 0) {
    *p = '\0';
#if DEBUG
    Serial.println("HTTP EOF");
#endif
    return false;
  }

  // read chars until EOL
  do {
    *p = c;
    p++;  
  } 
  while ((c = client->read()), c != 10 && c != 13 && c >= 0);
  *p = '\0';
#if DEBUG
  Serial.println(buffer);
#endif
  return true;
}


/**********************************
 *  Parse integer from http response
 ***********************************/
uint32_t http_int(EthernetClient *client) {
  uint16_t c;
  uint32_t n = 0;
  // search number
  while(c = client->read(), (c < '0' || c > '9') && c != -1);
  // if data isn't available, return zero
  if(c == -1)
    return 0;
  // parse number
  do {
    n *= 10;
    n += c - '0';
  } 
  while(c = client->read(), c >= '0' && c <= '9');
  return n;
}


/************************
 *
 *
 *    STRING Functions
 *
 *
 *************************/
/**********************************
 *  Parse integer from string
 ***********************************/
uint16_t parse_int(char *line) {
  uint16_t n = 0;
  char *c = line;
  // search number
  while(*c < '0' || *c > '9')
    c++;
  // parse number
  do {
    n *= 10;
    n += (*c) - '0';
    c++;
  } 
  while(*c >= '0' && *c <= '9');
  return n;
}


/************************************
 *  Write two digit number into stringia
 *************************************/
void two_dig(byte num, char *text) {
  if(num < 10) {
    *text = '0';
    *(text + 1) = '0' + num;
  }
  else {
    *text = (num / 10) + '0';
    *(text + 1) = (num % 10) + '0';
  }
}

/**************************************
 *  Write three digit number into string
 ***************************************/
void three_dig(byte num, char *text) {
  if(num < 100) {
    *text = '0';
  }
  else {
    *text = '0' + (num / 100);
  }
  two_dig(num % 100, text + 1);
}

/************************
 *
 *
 *    I/O Functions
 *
 *
 *************************/

/*************************************
 *  get data from soil moisture sensor
 **************************************/
byte soil_moisture() {
  return 100 - analogRead(SM_PIN) / 10.23;
}

/*************************************
 *  set ventilation relay
 **************************************/
void set_vent(boolean state) {
  digitalWrite(VENT_PIN, state ? HIGH : LOW);
}

/*************************************
 *  set watering relay
 **************************************/
void set_wat(boolean state) {
  digitalWrite(WAT_PIN, state ? HIGH : LOW);
}

#endif








